package top.yangbuyi.config.redis;

import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @description: 杨不易网站:www.yangbuyi.top
 * @program: yangbuyiopenHis2020
 * @ClassName: RedisConfig
 * @create: 2020-08-28 21:54
 * @author: yangbuyi
 * @since： JDK1.8
 * @RedisConfig: redis解决反序列化问题$
 **/
//@Configuration
//public class RedisConfig {
//
//	  /**
//	   * 重写Redis序列化方式，使用Json方式:
//	   * 当我们的数据存储到Redis的时候，我们的键（key）和值（value）都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer，StringRedisTemplate默认使用的是StringRedisSerializer。
//	   * Spring Data JPA为我们提供了下面的Serializer：
//	   * GenericToStringSerializer、Jackson2JsonRedisSerializer、JacksonJsonRedisSerializer、JdkSerializationRedisSerializer、OxmSerializer、StringRedisSerializer。
//	   * 在此我们将自己配置RedisTemplate并定义Serializer。
//	   *
//	   * @param redisConnectionFactory
//	   * @return
//	   */
//	  @Bean
//	  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//			RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//			redisTemplate.setConnectionFactory(redisConnectionFactory);
//
//			FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
//			// 全局开启AutoType，不建议使用
//			// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
//			// 建议使用这种方式，小范围指定白名单
////			ParserConfig.getGlobalInstance().addAccept("com.xiaolyuh.");
//
//			// 设置值（value）的序列化采用FastJsonRedisSerializer。
//			redisTemplate.setValueSerializer(fastJsonRedisSerializer);
//			redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
//			// 设置键（key）的序列化采用StringRedisSerializer。
//			redisTemplate.setKeySerializer(new StringRedisSerializer());
//			redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//
//			redisTemplate.afterPropertiesSet();
//			return redisTemplate;
//	  }
//
//}


@Configuration
public class RedisConfig extends CachingConfigurerSupport {

	  @Autowired
	  private RedisConnectionFactory redisConnectionFactory;


	  @Bean
	  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
			Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
			ObjectMapper objectMapper = new ObjectMapper();
			objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
			objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
			serializer.setObjectMapper(objectMapper);

			RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
			redisTemplate.setConnectionFactory(redisConnectionFactory);
			redisTemplate.setKeySerializer(new StringRedisSerializer());
			redisTemplate.setValueSerializer(serializer);
			redisTemplate.setHashKeySerializer(new StringRedisSerializer());
			redisTemplate.setHashValueSerializer(serializer);
			redisTemplate.afterPropertiesSet();

			return redisTemplate;
	  }

	  @Bean
	  public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
			RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
			RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
					.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
			return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
	  }
}